Постройте барплот (столбчатую диаграмму), отражающую распределение числа студентов по курсу обучения. Раскрасьте столбики любым понравившимся вам цветом (можно использовать как словесные обозначения, так и гекскоды). Добавьте цвет контура столбиков.
ggplot(hogwarts)+
geom_bar(aes(x = course,
fill = course),
colour = "black")+
labs(title = "Распределение числа студентов по курсу обучения",
x = "Курс",
y = "Количество учащихся",
fill = "Курс")+
scale_fill_manual(values = c("1" = "paleturquoise",
"2" = "darkseagreen1",
"3" = "darkolivegreen1",
"4" = "olivedrab2",
"5" = "palegreen3",
"6" = "seagreen3",
"7" = "turquoise4"))+
theme_custom+
theme(
panel.grid.major.y = element_line(colour = "grey80", linewidth = 0.5)
)
Создайте новый барплот, отражающий распределение числа студентов по факультету. Добавьте на график вторую факторную переменную – происхождение (bloodStatus). Оформите текст графика на русском языке. Для факультета “Gryffindor” при этом смени метку на оси на “Грифиндор”, а для факультета “Ravenclaw” – как “Когтевраан”. Модифицируйте график при помощи аргумента position так, чтобы каждый столбец показывал распределение факультета по чистоте крови в долях. Запишите текстом в qmd-документе, какой вывод можно сделать из графика?
Более половины учащихся школы волшебства Хогвартс являются полукровками, в то время как маглорожденные составляют менее представленную группу. В Гриффиндоре маглорожденные преобладают над числом чистокровных, тогда как в Когтевране и Пуффендуе они уступают им по количеству. В Слизерине маглорожденных вовсе не представлено.
ggplot(data = hogwarts, aes(x = house, fill = bloodStatus)) +
geom_bar(position = "fill", color = "black") +
labs(
title = "Распределение числа студентов по факультету и происхождению",
x = "Факультет",
y = "Доля учащихся",
fill = "Происхождение"
) +
scale_fill_manual(
values = c(
"half-blood" = "thistle2",
"muggle-born" = "thistle3",
"pure-blood" = "thistle4"
),
labels = c(
"half-blood" = "Полукровки",
"muggle-born" = "Маглорожденные",
"pure-blood" = "Чистокровные"
)
) +
scale_x_discrete(
labels = c(
"Gryffindor" = "Гриффиндор",
"Hufflepuff" = "Пуффендуй",
"Ravenclaw" = "Когтевран",
"Slytherin" = "Слизерин"
)
) +
theme_custom +
theme(
axis.text.x = element_text(angle = 45, hjust = 1),
panel.grid.major.y = element_line(colour = "grey80", linewidth = 0.5),
panel.grid.minor.y = element_line(colour = "grey90", linewidth = 0.3)
)
Отобразите распределение баллов, заработанных студентами на 3-й неделе обучения, по факультетам. Постарайтесь визуализировать одновременно и форму распределения,и некоторые описательные статистики. Отсортируйте факультеты в порядке убывания медианного балла за 3-ю неделю (мы не останавливались на этом в лекции, но упомянутая в ней функция по умолчанию сортирует именно по медиане,так что в этом случае дополнительных аргументов передавать не следует). Если вы используете geom_jitter, постарайтесь, чтобы точки лежали кучнее на оси, не отражающей собственно распределение. Проинтерпретируйте график.
На графике представлено распределение баллов студентов на 3-й неделе по факультетам и происхождению. В целом, разброс значений схож для всех факультетов: медианные значения близки к нулю, а диапазон колеблется от −20 до +25 баллов. Полукровки составляют наиболее устойчивую группу с умеренными колебаниями результатов. У маглорожденных наблюдается большая вариативность, особенно в Пуффендуе, где встречаются как высокие, так и низкие значения. Чистокровные показывают несколько более стабильные результаты, однако не демонстрируют значительного превосходства над другими категориями. В целом различия между факультетами и происхождением выражены слабо, что указывает на отсутствие явной зависимости между происхождением и академическими успехами.
ggplot(hogwarts) +
geom_boxplot(
aes(x = reorder(house, -week_3), y = week_3, fill = bloodStatus),
alpha = 0.8, linewidth = 0.5, width = 0.6
) +
geom_jitter(
aes(x = reorder(house, -week_3), y = week_3, color = bloodStatus),
size = 1.2, alpha = 0.6, width = 0.15
) +
labs(
title = "Распределение баллов на 3-й неделе по факультетам и происхождению",
x = "Факультет",
y = "Баллы",
fill = "Происхождение студентов",
color = "Происхождение студентов"
) +
scale_fill_manual(
values = c(
"pure-blood" = "thistle2",
"muggle-born" = "thistle3",
"half-blood" = "thistle4"
),
labels = c(
"half-blood" = "Полукровки",
"muggle-born" = "Маглорожденные",
"pure-blood" = "Чистокровные"
)
) +
scale_color_manual(
values = c(
"pure-blood" = "thistle2",
"muggle-born" = "thistle3",
"half-blood" = "thistle4"
),
labels = c(
"half-blood" = "Полукровки",
"muggle-born" = "Маглорожденные",
"pure-blood" = "Чистокровные"
)
) +
scale_x_discrete(
labels = c(
"Gryffindor" = "Гриффиндор",
"Hufflepuff" = "Пуффендуй",
"Ravenclaw" = "Когтевран",
"Slytherin" = "Слизерин"
)
) +
guides(color = "none") +
theme_custom +
theme(
panel.grid.major.y = element_line(colour = "grey80", linewidth = 0.5),
panel.grid.minor.y = element_line(colour = "grey90", linewidth = 0.3),
legend.title.align = 0.5,
axis.text.x = element_text(angle = 30, hjust = 1)
)
## Warning: The `legend.title.align` argument of `theme()` is deprecated as of ggplot2
## 3.5.0.
## ℹ Please use theme(legend.title = element_text(hjust)) instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
Постройте гистограмму для результата любого выбранного вами экзамена, кроме зельеварения. Настройте оптимальное, на ваш взгляд, число столбцов гистограммы. Выполните фасетирование по курсу. Постарайтесь, чтобы график был по возможности компактным.
-Обязательно выбирайте переменную Potions exam
num_bins <- 20 # количество столбцов гистограммы
ggplot(hogwarts, aes(x = `Herbology exam`)) +
geom_histogram(
bins = num_bins,
fill = "darkseagreen3",
color = "black",
alpha = 0.7
) +
labs(
title = "Распределение баллов за экзамен по травологии на разных курсах",
x = "Баллы",
y = "Количество студентов"
) +
facet_wrap(~ course, ncol = 3, scales = "free_y") +
theme_custom +
theme(
panel.grid.major.y = element_line(colour = "grey80", linewidth = 0.5),
strip.text = element_text(size = 10, face = "bold"),
axis.text = element_text(size = 10),
plot.title = element_text(hjust = 0.5, face = "bold"),
panel.spacing = unit(0.8, "lines")
)
Постройте скаттерплот, визуализирующий связь между суммарным баллом
студента за год и оценкой за экзамен по травологии.
Добавьте на график линию тренда. Удалите доверительную область и
сделайте линию прямой.
Подумайте, как избежать того, чтобы записать одни и те же координаты x и
y дважды.
Проинтерпретируйте график.
Линия тренда показывает положительную корреляцию, следовательно, студенты с более высокими баллами по Травологии чаще получают большое количество очков за год. Большая часть наблюдений принимает средние значения в диапазоне ~70-100 баллов за экзамен и ~-0–200 очков за год.
ggplot(hogwarts, aes(x = `Herbology exam`, y = result)) +
geom_point(
shape = 21,
fill = alpha("palegreen1", 0.6),
color = "black",
size = 3,
stroke = 0.8,
alpha = 0.6,
position = position_jitter(width = 2, height = 2)
) +
geom_smooth(
method = "lm",
se = FALSE,
color = "deeppink4",
linewidth = 1
) +
labs(
title = "Связь между результатом за экзамен по травологии\nи суммарными баллами за год",
x = "Баллы за экзамен по травологии",
y = "Суммарные очки за год"
) +
theme_custom +
theme(
plot.title = element_text(size = 18, hjust = 0.5, face = "bold"),
panel.grid.major.y = element_line(colour = "grey85", linewidth = 0.5),
panel.grid.minor = element_blank()
)
## `geom_smooth()` using formula = 'y ~ x'
Отобразите на одной иллюстрации скаттерплоты, аналогичные тому, что вы делали в предыдущем задании, для экзаменов по травологии, магловедению, нумерологии и зельеварению. На иллюстрации для каждого из четырех графиков также должна присутствовать линия тренда с характеристиками,аналогичными тем, что были в предыдущем пункте. Раскрасьте точки в разные цвета, в соответствии с факультетами. Используйте стандартные цвета факультетов (как в лекционных qmd). Проинтерпретируйте полученный результат.
На графиках, иллюстрирующих зависимость между суммарными годовыми баллами и оценками за экзамены по Нумерологии и Маггловедению, большая часть наблюдений сосредоточена в диапазонах примерно 40–70 баллов за экзамены и ~ -100–100 очков за год.
Травология демонстрирует самые высокие показатели: большинство значений лежит в диапазоне 50–100 баллов, за исключением кластера студентов Слизерина, у которых оценки находятся в пределах 25–50 баллов. Линия тренда указывает на положительную корреляцию, что свидетельствует о том, что учащиеся с более высокими годовыми баллами чаще получают высокие оценки на экзаменах по этим предметам.
В среднем студенты Когтеврана показывают более высокие результаты как за год, так и на экзаменах, тогда как учащиеся Гриффиндора и Пуффендуя демонстрируют показатели, близкие к средним значениям. Студенты Слизерина образуют два кластера: первый включает учеников с низкими оценками за экзамены и отрицательными годовыми баллами, второй — с высокими результатами, сопоставимыми с когтевранскими.
На графике, отражающем зависимость между годовыми баллами и оценками за экзамен по Зельеварению, распределение оценок за экзамен выглядит относительно равномерным. Однако высокие оценки в основном получают студенты Слизерина, тогда как учащиеся других факультетов демонстрируют низкие и средние баллы примерно в равной пропорции. Распределение годовых баллов по факультетам в целом соответствует тенденциям, наблюдаемым на других графиках.
Трансцендентальная апперцепция — это, согласно И. Канту, способность сознания объединять многообразие восприятий в единство опыта, обеспечивая тождество “Я” во всех актах мышления.
hogwarts_long <- hogwarts %>%
pivot_longer(cols = ends_with("exam"),
names_to = "exam_type",
values_to = "score")
hogwarts_long_filtered <- hogwarts_long %>%
filter(exam_type %in% c("Herbology exam", "Muggle studies exam", "Arithmancy exam", "Potions exam"))
scatterFacets <- hogwarts_long_filtered %>%
ggplot(aes(x = score, y = `result`, color = house)) +
geom_point( size = 3, alpha = 0.5) +
geom_smooth(se = FALSE, method = "lm", color = "blue") +
facet_wrap(~ exam_type, labeller = labeller(exam_type = c(
`Herbology exam` = "Травология",
`Muggle studies exam` = "Маггловедение",
`Arithmancy exam` = "Нумерология",
`Potions exam` = "Зельеварение"))) +
labs(title = "Связь между суммарными очками за год и оценками за экзамены",
x = "Оценка за экзамен",
y = "Суммарные очки за год",
fill = "Факультет")+
theme_custom +
scale_color_manual(name = "Факультет",
labels = c("Gryffindor" = "Гриффиндор",
"Hufflepuff" = "Пуффендуй",
"Ravenclaw" = "Когтевран",
"Slytherin" = "Слизерин"),
values = c("Gryffindor" = "#C50000",
"Hufflepuff" = "#ECB939",
"Ravenclaw" = "#41A6D9",
"Slytherin" = "#1F5D25"))
scatterFacets
## `geom_smooth()` using formula = 'y ~ x'
Видоизмените график, полученный на предыдущем шаге. Сгруппируйте и покрасьте линии тренда в соответствии с одной из категориальных переменных (с такой, которая подсвечивает одно из наблюдений на предыдущем этапе, относящееся ко всем 4-м экзаменам). Постарайтесь избежать коллизий в легенде, при этом сохранив и цветовую палитру для факультетов. Проинтерпретируйте результат.
При добавлении группировки по полу, с отображением разных форм точек для мальчиков и девочек, становится заметным бимодальное распределение студентов факультета Слизерин. Это распределение проявляется в виде двух отчетливо различимых кластеров: первая группа включает студентов с высокими итоговыми баллами за год, вторая — с низкими баллами. Интересно, что в большинстве случаев (3 из 4) оценка за экзамен у студентов Слизерина соответствует общему тренду, то есть студенты с высокими годовыми баллами получают высокие экзаменационные оценки, а с низкими — наоборот.
-Группируйте по переменной курса, она подходит больше всего.
Лучше я процитирую
стихотворение Г.Остера из сборника вредных советов:
Если вы по коридору
Мчитесь на велосипеде,
А навстречу вам из ванной
Вышел папа погулять,
Не сворачивайте в кухню,
В кухне – твердый холодильник.
Тормозите лучше в папу.
Папа мягкий. Он простит.
scatterFacets +
# Точки: цвет по факультету + форма по полу
geom_point(aes(fill = house, shape = sex),
size = 3, stroke = 0.8, alpha = 0.8) +
# Линии тренда: цвет по полу
geom_smooth(aes(x = score, y = result, color = sex),
se = FALSE, method = "lm", linewidth = 1) +
# Цвета заливки точек (факультет)
scale_fill_manual(
values = c(
"Gryffindor" = "#C50000",
"Hufflepuff" = "#ECB939",
"Ravenclaw" = "#41A6D9",
"Slytherin" = "#1F5D25"
),
labels = c(
"Gryffindor" = "Гриффиндор",
"Hufflepuff" = "Пуффендуй",
"Ravenclaw" = "Когтевран",
"Slytherin" = "Слизерин"
),
name = "Факультет",
guide = guide_legend(override.aes = list(shape = 21))
) +
# Цвета линий тренда (пол)
scale_color_manual(
values = c("male" = "green", "female" = "red"),
labels = c("male" = "Мужчины", "female" = "Женщины"),
name = "Пол"
) +
# Формы точек по полу
scale_shape_manual(
values = c("male" = 21, "female" = 24),
name = "Пол",
labels = c("male" = "Мужчины", "female" = "Женщины")
) +
labs(
title = "Связь между суммарными очками за год и оценками за экзамены, \nзависимость от факультета и пола студента",
x = "Оценка за экзамен",
y = "Суммарные очки за год"
) +
theme_custom +
theme(panel.grid.major.y = element_line(colour = "grey80", linewidth = 0.3))
## Scale for colour is already present.
## Adding another scale for colour, which will replace the existing scale.
## `geom_smooth()` using formula = 'y ~ x'
## `geom_smooth()` using formula = 'y ~ x'
Сравните распределение баллов за экзамен по прорицанию и за экзамен по защите от темных искусств. Сделайте это тремя разными способами. Под разными способами понимаются идеологически разные геомы или способы группировки. Не считаются разными способами изменения константных визуальных параметров (цвет заливки, размер фигур, другие чисто стилевые отличия) на сходных в остальном графиках. Объедините графики, таким образом, чтобы результирующий график имел два столбца и 2 строки. Два графика должны находиться в верхней строке и занимать равную площадь. Третий график должен занимать нижнюю строку целиком. Проинтерпретируйте график.
library(ggExtra)
library(ggridges)
library(patchwork)
theme_custom2 <- theme(
panel.background = element_rect(fill = "white"),
panel.grid.major = element_line(color = "grey85"),
plot.title = element_text(size = 20, hjust = 0.5),
plot.subtitle = element_text(size = 18, face = "bold", hjust = 0.5),
axis.text = element_text(size = 15),
axis.title = element_text(size = 15),
legend.title = element_text(size = 18),
legend.text = element_text(size = 15),
legend.position = "right",
legend.box = "horizontal",
plot.margin = margin(10, 35, 10, 10)
)
exam_scores_long <- hogwarts %>%
pivot_longer(cols = c(`Divinations exam`, `Defence against the dark arts exam`),
names_to = "exam", values_to = "score")
# 1. Гистограмма
histogram_plot <- ggplot(exam_scores_long, aes(x = score, fill = exam)) +
geom_histogram(alpha = 0.5, color = 'black', position = "identity", bins = 20) +
labs(subtitle = "Гистограмма", x = "Баллы", y = "Частота") +
scale_fill_manual(
name = "Экзамены",
values = c(`Divinations exam` = "cadetblue3",
`Defence against the dark arts exam` = "maroon"),
labels = c(`Divinations exam` = "Прорицание",
`Defence against the dark arts exam` = "Защита от тёмных искусств")
) +
theme_custom2 +
theme(legend.position = "none")
# 2. Boxplot
boxplot_plot <- ggplot(exam_scores_long, aes(y = score, fill = exam)) +
geom_boxplot(outlier.size = 2, alpha = 0.7) +
labs(subtitle = "Boxplot", y = "Баллы", x = NULL) +
scale_fill_manual(
name = "Экзамены",
values = c(`Divinations exam` = "cadetblue3",
`Defence against the dark arts exam` = "maroon"),
labels = c(`Divinations exam` = "Прорицание",
`Defence against the dark arts exam` = "Защита от тёмных искусств")
) +
theme_custom2 +
theme(legend.position = "none")
# 3. Скаттерплот
scatter_plot <- exam_scores_long %>%
mutate(exam = recode(exam,
`Divinations exam` = "Прорицание",
`Defence against the dark arts exam` = "Защита от\nтёмных\nискусств")) %>%
ggplot(aes(x = score, y = exam, color = exam)) +
geom_point(position = position_jitter(width = 0.1, height = 0.1), alpha = 0.7) +
labs(subtitle = "Скаттерплот", y = "Экзамены", x = "Баллы") +
scale_color_manual(
name = "Экзамены",
values = c("Прорицание" = "cadetblue3",
"Защита от\nтёмных\nискусств" = "maroon"),
labels = c("Прорицание" = "Прорицание",
"Защита от\nтёмных\nискусств" = "Защита от тёмных искусств")
) +
theme_custom2
# --- Комбинация графиков через patchwork ---
combined_plot <- (histogram_plot + boxplot_plot) / scatter_plot +
plot_annotation(
title = "Распределение баллов за экзамен по Прорицанию и Защите от тёмных искусств",
theme = theme(
plot.title = element_text(size = 20, hjust = 0.5, face = "bold")
)
)
combined_plot
-Одной из фигур должна быть гистограмма с 47-ю столбцами и цветом столбиков orchid2.
Okey, anyways…
lovushka_plot <- ggplot(exam_scores_long, aes(x = score, fill = exam)) +
geom_histogram(alpha = 0.5, color = 'black', position = "identity", bins = 47) +
labs(subtitle = "Гистограмма", x = "Баллы", y = "Частота") +
scale_fill_manual(
name = "Экзамены",
values = c(`Divinations exam` = "orchid2",
`Defence against the dark arts exam` = "orchid2"),
labels = c(`Divinations exam` = "Прорицание",
`Defence against the dark arts exam` = "Защита от тёмных искусств")
) +
theme_custom2 +
theme(legend.position = "none")
lovushka_plot
Визуализируйте средний балл по зельеварению студентов с различным происхождением. Сделайте это, построив столбиковую диаграмму. Вы вольны добавить дополнительные детали и информацию на график, например, какую-то из мер рассеяния и текстовые элементы. Измените порядок ваших фигур слева направо следующим образом: маглорожденные, полукровки, чистокровные. Проинтерпретируйте результат. Как вы думаете, почему он именно такой? Если у вас есть гипотеза, проиллюстрируйте ее еще одним графиком (или графиками).
На верхнем графике видно, что чистокровные студенты имеют самый высокий средний балл по зельеварению (52), за ними идут полукровки (46), а магглорожденные — 35.
На нижнем графике Слизеринцы всех категорий происхождения показывают высокие средние баллы (83–86), тогда как у остальных факультетов баллы ниже 50, с наименьшими у магглорожденных Гриффиндора и наибольшими у магглорожденных Пуффендуя, что отражает различия в успехах по зельеварению между факультетами.
-Сделайте это, построив столбиковую диаграмму. - no, столбиковые диаграммы не очень хорошо
подходят для визуализации средних, поскольку теряется физический смысл у
объемов столбиков (который обычно обозначает штуки или доли).
library(forcats)
library(patchwork)
prepare_data <- function(data) {
data %>%
mutate(
bloodStatus = fct_recode(
bloodStatus,
`Магглорожденные` = "muggle-born",
`Чистокровные` = "pure-blood",
`Полукровки` = "half-blood"
),
bloodStatus = fct_relevel(bloodStatus,
"Магглорожденные", "Чистокровные", "Полукровки")
)
}
# --- 1. Средний балл по происхождению ---
bar_plot_potions1 <- hogwarts_long %>%
filter(exam_type == "Potions exam") %>%
group_by(bloodStatus) %>%
summarize(mean_potions_score = round(mean(score, na.rm = TRUE), 0), .groups = 'drop') %>%
prepare_data()
blood_plot1 <- ggplot(bar_plot_potions1, aes(x = bloodStatus, y = mean_potions_score, color = bloodStatus)) +
geom_point(size = 8) +
geom_text(aes(label = mean_potions_score), vjust = -1, color = "black", size = 5, fontface = "bold") +
labs(subtitle = "Зависимость от происхождения",
x = "Происхождение", y = "Средний балл") +
scale_color_manual(
name = "Происхождение",
values = c(
"Магглорожденные" = "cyan",
"Чистокровные" = "royalblue",
"Полукровки" = "skyblue"
)) +
theme_custom2 +
scale_y_continuous(limits = c(25, 75)) +
theme(
plot.subtitle = element_text(size = 16, hjust = 0.5, face = "italic"),
legend.position = "bottom"
)
# --- 2. Средний балл по происхождению и факультету ---
bar_plot_potions2 <- hogwarts_long %>%
filter(exam_type == "Potions exam") %>%
group_by(bloodStatus, house) %>%
summarize(mean_potions_score = round(mean(score, na.rm = TRUE), 0), .groups = 'drop') %>%
prepare_data() %>%
mutate(
house = recode(house,
"Gryffindor" = "Гриффиндор",
"Hufflepuff" = "Пуффендуй",
"Ravenclaw" = "Когтевран",
"Slytherin" = "Слизерин"),
`blood and house` = paste(bloodStatus, "&", house),
`blood and house_wrapped` = str_wrap(`blood and house`, width = 15)
)
blood_plot2 <- ggplot(bar_plot_potions2, aes(
x = mean_potions_score,
y = fct_reorder(`blood and house_wrapped`, mean_potions_score),
color = house
)) +
geom_point(size = 5) +
geom_text(aes(label = mean_potions_score), hjust = -0.3, color = "black", size = 5, fontface = "bold") +
labs(subtitle = "Зависимость от происхождения и факультета",
x = "Средний балл", y = NULL) +
scale_x_continuous(breaks = seq(0, 100, by = 10), limits = c(25, 90)) +
scale_color_manual(
name = "Факультет",
values = c(
"Гриффиндор" = "#C50000",
"Пуффендуй" = "#ECB939",
"Когтевран" = "#41A6D9",
"Слизерин" = "#1F5D25"
)
) +
theme_custom2 +
coord_flip() +
theme(
plot.subtitle = element_text(size = 16, hjust = 0.5, face = "italic"),
axis.text.x = element_text(angle = 45, size = 12),
legend.position = "right"
)
# --- 3. Объединяем через patchwork ---
combined_plot <- blood_plot1 / blood_plot2 +
plot_annotation(
title = "Средний балл по зельеварению",
theme = theme(plot.title = element_text(face = "bold", size = 22, hjust = 0.5))
) & theme(legend.position = "right")
combined_plot
Изобразите на графике диаграмму рассеяния (скаттерплот), где на осях
располагались бы результаты экзаменов по заклинаниям и по древним
рунам.
На графике присутствует некоторая проблема. Если вы затрудняетесь ее
идентифицировать, то можете взять подсказку – для этого постройте
скаттерплот для датасета podskazka.csv, лежащего в папке
data архива из домашнего задания – по оси x отобразите
переменную у, а по оси y – переменную х и с
настройкой лимитов по оси y от 200 до 500.
Предложите и подкрепите визуализациями не менее 3-х способов решения
означенной проблемы.
При построении базового скаттерплота было выявлено явление оверплоттинга — ситуация, при которой значительное количество наблюдений имеет одинаковые или близкие координаты и, вследствие этого, точки на графике перекрывают друг друга. Такое наложение снижает информативность и затрудняет визуальное восприятие данных.
Для решения данной проблемы были рассмотрены несколько подходов:
Добавление прозрачности и смещения точек
(jittering).
Этот способ позволяет частично визуализировать плотность перекрывающихся
наблюдений за счёт уменьшения непрозрачности и небольшого случайного
смещения координат точек. Однако в нашем случае данный метод оказался
малоэффективным, поскольку число совпадающих значений слишком велико, и
даже значительное снижение прозрачности или сильное смещение не
обеспечивает читаемости распределения.
Масштабирование точек по числу наблюдений и построение
тепловой карты.
Данный подход оказался более результативным. Использование функции
geom_count() или построение двумерной тепловой карты
(geom_bin2d(), stat_density_2d()) позволяет
явно показать области с высокой концентрацией студентов. Это значительно
повышает наглядность, особенно при сравнении результатов по двум
экзаменам.
Использование альтернативных типов
визуализаций.
Для анализа распределений и взаимосвязей можно использовать
гистограммы и графики плотности (density
plots). Эти типы графиков более наглядно отображают
закономерности в распределении баллов, показывая, где сосредоточено
большинство наблюдений.
Таким образом, при высокой плотности совпадающих точек наиболее информативными оказываются методы агрегирования и визуализации плотности, позволяющие избежать потери данных и улучшить читаемость графика.
scatter_data <- hogwarts %>%
select(`Charms exam`, `Study of ancient runes exam`)
# Строим скаттерплот
ggplot(scatter_data, aes(x = `Charms exam`, y = `Study of ancient runes exam`)) +
geom_point(size = 3, alpha = 1, color = "mediumpurple1") +
labs(
title = "Сравнение результатов экзаменов\n по заклинаниям и древним рунам",
x = "Экзамен по заклинаниям",
y = "Экзамен по древним рунам"
) +
theme_custom
#1 Прозрачность точек
ggplot(scatter_data, aes(x = `Charms exam`, y = `Study of ancient runes exam`)) +
geom_point(size = 3, alpha = 0.4, color = "mediumpurple1") +
labs(title = "Сравнение результатов экзаменов\n по заклинаниям и древним рунам (alpha)",
x = "Экзамен по заклинаниям",
y = "Экзамен по древним рунам") +
theme_custom
#2 Смещение точек
ggplot(scatter_data, aes(x = `Charms exam`, y = `Study of ancient runes exam`)) +
geom_point(position = position_jitter(width = 0.7, height = 0.7),
size = 3, alpha = 0.3, color = "mediumpurple1") +
labs(title = "Сравнение результатов экзаменов\n по заклинаниям и древним рунам (jitter+alpha)",
x = "Экзамен по заклинаниям",
y = "Экзамен по древним рунам") +
theme_custom
#3 точки масштабируются по числу наблюдений в каждой позиции
ggplot(scatter_data, aes(x = `Charms exam`, y = `Study of ancient runes exam`)) +
geom_count(aes(size = ..n.., color = ..n..)) +
scale_size_continuous(name = "Количество") +
scale_color_viridis(option = "C", name = "Количество") +
guides(size = guide_legend(), color = guide_legend()) +
labs(title = "Сравнение результатов экзаменов\nпо заклинаниям и древним рунам\n (масштабирование точек)",
x = "Экзамен по заклинаниям",
y = "Экзамен по древним рунам")+
theme_custom
## Warning: The dot-dot notation (`..n..`) was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(n)` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
#4 Вариант с geom_bin2dlibrary(viridis) строит тепловую карту по плотности точек
ggplot(scatter_data, aes(x = `Charms exam`, y = `Study of ancient runes exam`)) +
geom_bin2d(bins = 20) +
scale_fill_viridis(name = "Количество", option = "D") +
labs(title = "Сравнение результатов экзаменов\n по заклинаниям и древним рунам\n (тепловая карта)",
x = "Экзамен по заклинаниям",
y = "Экзамен по древним рунам") +
theme_custom
#другие виды графиков для представления
scatter_long <- scatter_data %>%
pivot_longer(cols = c(`Charms exam`, `Study of ancient runes exam`),
names_to = "exam", values_to = "score")
ggplot(scatter_long, aes(x = score, fill = exam)) +
geom_histogram(position = "identity", alpha = 0.6, bins = 20, color = "black") +
scale_fill_viridis(discrete = TRUE, option = "H", name = "Экзамен",
labels = c("Charms exam" = "Заклинания",
"Study of ancient runes exam" = "Древние руны")) +
labs(title = "Распределение оценок по экзаменам",
x = "Баллы", y = "Количество студентов") +
theme_minimal(base_size = 15)
ggplot(scatter_long, aes(x = score, fill = exam)) +
geom_density(alpha = 0.6) +
scale_fill_viridis(discrete = TRUE, option = "H", name = "Экзамен",
labels = c("Charms exam" = "Заклинания",
"Study of ancient runes exam" = "Древние руны")) +
labs(title = "Плотность распределения оценок по экзаменам",
x = "Баллы", y = "Плотность") +
theme_minimal(base_size = 15)
Используйте датасет с набором баллов по неделям для первых 30-и
студентов, который мы получили на лекции. Постройте лайнплоты для всех
студентов. Выделите при помощи пакета gghighlight студентов
с факультета Когтевран, на лейблах отразите их происхождение. Линии, не
относящиеся к студентам-когтевранцам покрасьте в небесно-голубой цвет,
толщину их настройте на уровне не более трети от стандартной.
hogwarts_subset <- hogwarts %>%
select(id, house, bloodStatus,starts_with("week_"))%>%
slice(1:30)
# 2. Переводим данные из wide в long формат
hogwarts_long2 <- hogwarts_subset %>%
pivot_longer(
cols = starts_with("week_"),
names_to = "week",
values_to = "score"
) %>%
mutate(week = str_remove(week, "week_") %>% as.integer())
# 3. Строим лайнплот
ggplot(hogwarts_long2, aes(x = week, y = score, group = id)) +
geom_line(size = 0.6) +
gghighlight(
house == "Ravenclaw",
label_key = bloodStatus,
use_direct_label = TRUE,
unhighlighted_params = list(color = "skyblue", size = 0.3),
label_params = list(size = 3, fontface = "bold", max.overlaps = 20)
) +
labs(
title = "Баллы студентов по неделям",
x = "Неделя",
y = "Баллы"
) +
theme_custom2
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## Warning: Tried to calculate with group_by(), but the calculation failed.
## Falling back to ungrouped filter operation...
Воспроизведите график максимально близко к оригиналу и
проинтерпретируйте его.
ggplot(hogwarts,
aes(x = interaction(sex, house), y = result, fill = house)) +
geom_violin(scale = "area",
width = 1.5,
trim = TRUE,
linewidth = 0.7) +
geom_boxplot(width = 0.1,
outlier.shape = NA,
fill = "white",
color = "grey40") +
# Средние значения за весь год для каждого факультета
stat_summary(
aes(group = house), # средние по факультету
fun = mean,
geom = "point",
shape = 23,
size = 10,
color = "black",
fill = "brown",
stroke = 2
) +
geom_hline(yintercept = 0, linetype = "dashed", color = "salmon", size = 2) +
scale_fill_manual(labels = c("Gryffindor" = "Гриффиндор",
"Hufflepuff" = "Пуффендуй",
"Ravenclaw" = "Когтевран",
"Slytherin" = "Слизерин"),
values = c("Gryffindor" = "#C50000",
"Hufflepuff" = "#ECB939",
"Ravenclaw" = "#41A6D9",
"Slytherin" = "#1F5D25")
) +
scale_y_continuous(breaks = seq(-300, 250, by = 50)) +
labs(
title = "Баллы студентов Хогвартса",
subtitle = "Распределение числа баллов у студентов различных факультетов Хогвартса в 2024-2025 учебном году",
x = NULL,
y = "Количество очков",
fill = "Факультет",
caption = "Источник: нездоровая фантазия автора лекции"
) +
facet_wrap(~ sex, ncol = 2,
strip.position = "top",
labeller = as_labeller(c(female = "Девочки", male = "Мальчики"))) +
theme_custom +
theme(
plot.title = element_text(size = 24, face = "bold", hjust = 0.5, family = "serif"),
plot.subtitle = element_text(size = 18, hjust = 0.5, colour = "burlywood4"),
axis.title.y = element_text(size = 20, family = "serif"),
axis.text.y = element_text(size = 14, family = "serif"),
strip.text = element_text(size = 20, family = "serif"),
legend.position = c(0.5, 0.08),
legend.direction = "vertical",
axis.text.x = element_blank(),
legend.title = element_text(size = 22, family = "serif"),
legend.text = element_text(size = 18, family = "serif", face = "italic"),
panel.grid = element_blank(),
panel.background = element_rect(fill = "white", color = "black", linewidth = 1),
panel.border = element_rect(fill = NA, color = "black", linewidth = 1)
) +
guides(fill = guide_legend(override.aes = list(size = 5))) +
annotate(
"text",
x = Inf,
y = Inf,
label = "Нет ручек – нет конфетки",
hjust = 1.1,
vjust = 1.1,
color = "white",
size = 1
)
## Warning: A numeric `legend.position` argument in `theme()` was deprecated in ggplot2
## 3.5.0.
## ℹ Please use the `legend.position.inside` argument of `theme()` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.